home *** CD-ROM | disk | FTP | other *** search
/ HyperLib 1997 Winter - Disc 1 / HYPERLIB-1997-Winter-CD1.ISO.7z / HYPERLIB-1997-Winter-CD1.ISO / オンラインウェア / PRG / ICProgKit 1.3.sit / ICProgKit1.3 / Goodies / ICeTEe / ICeTEe.p next >
Text File  |  1996-07-20  |  10KB  |  400 lines

  1. unit ICeTEe;
  2.  
  3. interface
  4.  
  5.     procedure Main;
  6.  
  7. implementation
  8.  
  9.     uses
  10.         Processes, SysEqu, Notification, Traps, 
  11.  
  12.         ShowInit75, 
  13.  
  14.         ICTypes, ICCAPI;
  15.  
  16.     const
  17.         MenuFlash = $A24;
  18.         ToolScratch = $9CE;
  19.  
  20.     const
  21.         kCreator = 'ICTE';
  22.  
  23.     const
  24.         (* EXCL *)
  25.         rExclusions = 128;
  26.  
  27.         (* ICN# *)
  28.         rICTEIcon = 128;
  29.         rFailedIcon = 129;
  30.  
  31.         (* STR# *)
  32.         rErrorStrings = 128;
  33.         strMiscErr = 1;
  34.         strNoCMErr = 2;
  35.         strNoICErr = 3;
  36.         strInsufficientICErr = 4;
  37.         strNoMemoryErr = 5;
  38.         strCantFindHelperErr = 6;
  39.         strNoHelperErr = 7;
  40.         strNoURLErr = 8;
  41.         strCantHackIt = 9;
  42.  
  43.     const
  44.         noCMErr = -6660;
  45.  
  46.     type
  47.         exArray = array[1..1000] of OSType;
  48.         exPtr = ^exArray;
  49.         exHandle = ^exPtr;
  50.  
  51.         icteGlobals = record
  52.                 signature: OSType;
  53.                 version: NumVersion;
  54.                 exclusions: exHandle;
  55.                 errors: Handle;
  56.                 old_teclick: ProcPtr;
  57.             end;
  58.         icteGlobalsPtr = ^icteGlobals;
  59.         icteGlobalsPtrPtr = ^icteGlobalsPtr;
  60.  
  61.     function GetIndStrH (h: handle; index: integer): str255;
  62.     (* Stolen directly from PNL's MyStrH unit *)
  63.         var
  64.             count, i: integer;
  65.             s: str255;
  66.             ps: longInt;
  67.     begin
  68.         count := integerPtr(h^)^;
  69.         if (1 <= index) and (index <= count) then begin
  70.             ps := SizeOf(integer);
  71.             for i := 1 to index - 1 do
  72.                 ps := ps + BAND(ptr(ord(h^) + ps)^, $FF) + 1;
  73.             BlockMove(ptr(ord(h^) + ps), @s, BAND(ptr(ord(h^) + ps)^, $FF) + 1);
  74.         end
  75.         else begin
  76.             s := '';
  77.         end;
  78.         GetIndStrH := s;
  79.     end;
  80.  
  81.     function DecStr (l: longint): Str32;
  82.         var
  83.             tmp: Str255;
  84.     begin
  85.         NumToString(l, tmp);
  86.         DecStr := tmp;
  87.     end; (* DecStr *)
  88.  
  89.     function GetMyGlobals: icteGlobalsPtr;
  90.     begin
  91.         GetMyGlobals := icteGlobalsPtrPtr(@Main)^;
  92.     end; (* GetMyGlobals *)
  93.  
  94.     procedure SetMyGlobals (globals: icteGlobalsPtr);
  95.         var
  96.             tmp: icteGlobalsPtrPtr;
  97.     begin
  98.         tmp := icteGlobalsPtrPtr(@Main);
  99.         tmp^ := globals;
  100.     end; (* SetMyGlobals *)
  101.  
  102.     function CurrentProcessExcluded: boolean;
  103.         var
  104.             PSN: ProcessSerialNumber;
  105.             info: ProcessInfoRec;
  106.             exclusions: exHandle;
  107.             i: integer;
  108.     begin
  109.         PSN.highLongOfPSN := 0;
  110.         PSN.lowLongOfPSN := kCurrentProcess;
  111.         info.processInfoLength := sizeof(ProcessInfoRec);
  112.         info.processName := nil;
  113.         info.processAppSpec := nil;
  114.         if GetProcessInformation(PSN, info) = noErr then begin
  115.             exclusions := GetMyGlobals^.exclusions;
  116.             CurrentProcessExcluded := false;
  117.             for i := 1 to GetHandleSize(Handle(exclusions)) div 4 do begin
  118.                 if exclusions^^[i] = info.processSignature then begin
  119.                     CurrentProcessExcluded := true;
  120.                     leave;
  121.                 end; (* if *)
  122.             end; (* for *)
  123.         end
  124.         else begin
  125.             CurrentProcessExcluded := true;
  126.         end; (* if *)
  127.     end; (* CurrentProcessExcluded *)
  128.  
  129.     function HaveComponentManager: boolean;
  130.         var
  131.             response: longint;
  132.     begin
  133.         HaveComponentManager := (Gestalt(gestaltComponentMgr, response) = noErr);
  134.     end; (* HaveComponentManager *)
  135.  
  136.     function DoCommandClick (teh: TEHandle; selStart, selEnd: longint): ICError;
  137.         var
  138.             inst: ComponentInstance;
  139.             err: ICError;
  140.             err2: ICError;
  141.             text: Handle;
  142.             s: signedByte;
  143.             rgn: RgnHandle;
  144.             i: integer;
  145.             junklong: longint;
  146.             hint, at: Str31;
  147.             urlh: Handle;
  148.             tmpSelStart, tmpSelEnd: longint;
  149.     begin
  150.         if HaveComponentManager then begin
  151.             err := ICCStart(inst, kCreator);
  152.         end
  153.         else begin
  154.             err := noCMErr;
  155.         end; (* if *)
  156.         if err = noErr then begin
  157.             err := ICCFindConfigFile(inst, 0, nil);
  158.             if err = noErr then begin
  159.                 text := Handle(TEGetText(teh));
  160.                 s := HGetState(text);
  161.                 HLock(text);
  162.                 urlh := NewHandle(0);
  163.                 hint := 'mailto';
  164.                 tmpSelStart := selStart;
  165.                 tmpSelEnd := selEnd;
  166.                 err := ICCParseURL(inst, hint, text^, GetHandleSize(text), tmpSelStart, tmpSelEnd, urlh);
  167.                 if err = noErr then begin
  168.                     hint := '';
  169.                     at := '@';
  170.                     if Munger(urlh, 0, @at[1], length(at), nil, 0) >= 0 then begin
  171.                         hint := 'mailto';
  172.                     end;
  173.                     err := ICCLaunchURL(inst, hint, text^, GetHandleSize(text), selStart, selEnd);
  174.                 end;
  175.                 DisposeHandle(urlh);
  176.                 TESetSelect(selStart, selEnd, teh);
  177.                 if err = noErr then begin
  178.                     for i := 1 to integerPtr(MenuFlash)^ do begin
  179.                         Delay(5, junklong);
  180.                         TEDeactivate(teh);
  181.                         Delay(5, junklong);
  182.                         TEActivate(teh);
  183.                     end; (* for *)
  184.                 (* leave the URL selected *)
  185.                 end; (* if *)
  186.                 HSetState(text, s);
  187.             end; (* if *)
  188.             err2 := ICCStop(inst);
  189.             if err = noErr then begin
  190.                 err := err2;
  191.             end; (* if *)
  192.         end; (* if *)
  193.         DoCommandClick := err;
  194.     end; (* DoCommandClick *)
  195.  
  196.     procedure MyNMResponseProc (nm: NMRecPtr);
  197.         var
  198.             ozone: THz;
  199.             strh: Handle;
  200.             junk: OSErr;
  201.     begin
  202.         junk := NMRemove(nm);
  203.         ozone := GetZone;
  204.         SetZone(SystemZone);
  205.         strh := RecoverHandle(Ptr(nm^.nmStr));
  206.         if strh <> nil then begin
  207.             DisposeHandle(strh);
  208.         end; (* if *)
  209.         DisposePtr(Ptr(nm));
  210.         SetZone(ozone);
  211.     end; (* MyNMResponseProc *)
  212.  
  213.     procedure MyTEClick (teh: TEHandle; old_selStart, old_selEnd: integer);
  214.         var
  215.             err: ICError;
  216.             message: Str255;
  217.             nm: NMRecPtr;
  218.             strindex: integer;
  219.             strh: StringHandle;
  220.     begin
  221.         if not CurrentProcessExcluded then begin
  222.             if not ((old_selStart <= teh^^.selStart) and (teh^^.selStart <= old_selEnd) and (old_selStart <= teh^^.selEnd) and (teh^^.selEnd <= old_selEnd)) then begin
  223.                 old_selStart := teh^^.selStart;
  224.                 old_selEnd := teh^^.selEnd;
  225.             end; (* if *)
  226.             err := DoCommandClick(teh, old_selStart, old_selEnd);
  227.             if err <> noErr then begin
  228.                 (* can't case on the error codes because MPW Pascal does not case on longints properly *)
  229.                 if err = badComponentInstance then begin
  230.                     strindex := strNoICErr;
  231.                 end
  232.                 else if err = noCMErr then begin
  233.                     strindex := strNoCMErr;
  234.                 end
  235.                 else if err = badComponentSelector then begin
  236.                     strindex := strInsufficientICErr;
  237.                 end
  238.                 else if err = memFullErr then begin
  239.                     strindex := strNoMemoryErr;
  240.                 end
  241.                 else if err = afpItemNotFound then begin
  242.                     strindex := strCantFindHelperErr;
  243.                 end
  244.                 else if err = icPrefNotFoundErr then begin
  245.                     strindex := strNoHelperErr;
  246.                 end
  247.                 else if err = icNoURLErr then begin
  248.                     strindex := strNoURLErr;
  249.                 end
  250.                 else if err = noPortErr then begin
  251.                     strindex := strCantHackIt;
  252.                 end
  253.                 else begin
  254.                     strindex := strMiscErr;
  255.                 end; (* if *)
  256.                 message := GetIndStrH(GetMyGlobals^.errors, strindex);
  257.                 if message <> '' then begin
  258.                     strindex := Pos('^0', message);
  259.                     if strindex <> 0 then begin
  260.                         Delete(message, strindex, 2);
  261.                         Insert(DecStr(err), message, strindex);
  262.                     end; (* if *)
  263.                     strh := NewString(message);
  264.                     HLock(Handle(strh));
  265.                     nm := NMRecPtr(NewPtrSysClear(sizeof(NMRec)));
  266.                     if nm <> nil then begin
  267.                         nm^.qType := ord(nmType);
  268.                         nm^.nmMark := 0;
  269.                         nm^.nmIcon := nil;
  270.                         nm^.nmSound := nil;
  271.                         nm^.nmStr := strh^;
  272.                         nm^.nmResp := @MyNMResponseProc;
  273.                         err := NMInstall(nm);
  274.                     end
  275.                     else begin
  276.                         SysBeep(10);
  277.                     end; (* if *)
  278.                 end; (* if *)
  279.             end; (* if *)
  280.         end; (* if *)
  281.     end; (* MyTEClick *)
  282.  
  283.     procedure CallTEClick (pt: Point; fExtend: boolean; teh: TEHandle; proc: ProcPtr);
  284.     inline
  285.         $205F, (* move.l    (a7)+,a0            ; pop proc address    *)
  286.         $4E90; (* jsr            (a0)                ; call proc                *)
  287.  
  288.     procedure InlinePushAll;
  289.     inline
  290.         $48E7, $FFFC;
  291.  
  292.     procedure InlinePopAll;
  293.     inline
  294.         $4CDF, $3FFF;
  295.  
  296.     procedure PascalTEClickPatch (pt: Point; fExtend: boolean; teh: TEHandle);
  297.         var
  298.             old_selStart, old_selEnd: integer;
  299.             globals: icteGlobalsPtr;
  300.             ozone: THz;
  301.             command_key: boolean;
  302.             km: KeyMap;
  303.     begin
  304.         InlinePushAll;
  305.         globals := GetMyGlobals;
  306.         old_selStart := teh^^.selStart;
  307.         old_selEnd := teh^^.selEnd;
  308.         GetKeys(km);
  309.         command_key := km[55];
  310.         CallTEClick(pt, fExtend, teh, globals^.old_teclick);
  311.         if command_key and (GetHandleSize(Handle(TEGetText(teh))) > 0) then begin
  312.             ozone := GetZone;
  313.             SetZone(SystemZone);
  314.             MyTEClick(teh, old_selStart, old_selEnd);
  315.             SetZone(ozone);
  316.         end; (* if *)
  317.         InlinePopAll;
  318.     end; (* PascalTEClickPatch *)
  319.  
  320.     function MyGestalt (selector: OSType; var response: longint): OSErr;
  321.         var
  322.             globals: icteGlobalsPtr;
  323.     begin
  324.         globals := GetMyGlobals;
  325.         response := longint(globals);
  326.         MyGestalt := noErr;
  327.     end; (* MyGestalt *)
  328.  
  329.     procedure Main;
  330.         var
  331.             ozone: THz;
  332.             err: OSErr;
  333.             err2: OSErr;
  334.             response: longint;
  335.             globals: icteGlobalsPtr;
  336.             exclusions: Handle;
  337.             errors: Handle;
  338.             vers: VersRecHndl;
  339.     begin
  340. (* Debugger; *)
  341.         (* detach our resource *)
  342.         DetachResource(RecoverHandle(Ptr(longintPtr(ToolScratch)^)));
  343.         ShowIcon7(rICTEIcon, false);
  344.         ozone := GetZone;
  345.         SetZone(SystemZone);
  346.         (* check for System 7 *)
  347.         err := noErr;
  348.         if (Gestalt(gestaltSystemVersion, response) <> noErr) | (response < $700) then begin
  349.             err := unimpErr;
  350.         end; (* if *)
  351.         (* create the globals *)
  352.         if err = noErr then begin
  353.             globals := icteGlobalsPtr(NewPtrSysClear(sizeof(icteGlobals)));
  354.             err := MemError;
  355.         end; (* if *)
  356.         if err = noErr then begin
  357.             (* install globals *)
  358.             SetMyGlobals(globals);
  359.             globals := GetMyGlobals;
  360.             (* init globals *)
  361.             globals^.signature := kCreator;
  362.             vers := VersRecHndl(Get1Resource('vers', 1));
  363.             if vers <> nil then begin
  364.                 globals^.version := vers^^.numericVersion;
  365.             end; (* if *)
  366.             exclusions := Get1Resource('EXCL', rExclusions);
  367.             err := HandToHand(exclusions);
  368.             globals^.exclusions := exHandle(exclusions);
  369.             errors := Get1Resource('STR#', rErrorStrings);
  370.             err2 := HandToHand(errors);
  371.             globals^.errors := errors;
  372.             if err = noErr then begin
  373.                 err := err2;
  374.             end; (* if *)
  375.         end; (* if *)
  376.         (* register gestalt *)
  377.         if err = noErr then begin
  378.             err := NewGestalt(kCreator, @MyGestalt);
  379.         end; (* if *)
  380.         if err = noErr then begin
  381.         (* install our patch *)
  382.             globals^.old_teclick := ProcPtr(NGetTrapAddress(_TEClick, ToolTrap));
  383.             NSetTrapAddress(longint(@PascalTEClickPatch), _TEClick, ToolTrap);
  384.         end; (* if *)
  385.         (* if we got an error then we bleed memory all over the place, this is not an accident *)
  386.         (* how many copies of the init can you reasonably fail to install??? *)
  387.         SetZone(ozone);
  388.  
  389.         if err = noErr then begin
  390.             ShowIcon7(rICTEIcon, true);
  391.         end
  392.         else begin
  393.             ShowIcon7(rFailedIcon, true);
  394.         end; (* if *)
  395.     end; (* Main *)
  396.  
  397. end. (* ICeTEe *)
  398. selStartX, selEndX: longint;
  399. selStartX := selStart;
  400. selEndX := selEnd;